package com.yanqu.road.entity.activity.daomu.config;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.daomu.*;
import com.yanqu.road.entity.activity.daomu.enums.*;
import com.yanqu.road.entity.activity.daomu.param.DaoMuOpenBoxRes;
import com.yanqu.road.entity.config.system.NormalWeightItem;
import com.yanqu.road.entity.config.system.PropertyWeightItem;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.eGoodsType;
import com.yanqu.road.utils.ListHelper;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class DaoMuActivityConfig {

    //活动id
    private int activityId;

    //活动信息
    private ActivityInfo activityInfo;

    //活动配置信息
    private Map<String, ActivityConfig> activityConfigMap;

    //关卡配置
    private Map<Integer, DaoMuMissionConfig> daoMuMissionConfigMap;

    //NPC配置
    private Map<Integer, DaoMuNpcConfig> daoMuNpcConfigMap;

    //活动物品配置
    private Map<Integer, DaoMuCurioConfig> daoMuCurioConfigMap;
    private List<DaoMuCurioConfig> daoMuCurioConfigList;//按等级排序的物品配置

    //等级配置
    private Map<Integer, DaoMuPlayerLevelConfig> levelConfigMap;

    //排序好的等级配置
    private List<DaoMuPlayerLevelConfig> levelConfigList;

    //技能配置
    private Map<Integer, DaoMuSkillConfig> skillConfigMap;
    //K：技能id_技能等级,V:DaoMuSkillConfig
    private Map<String, DaoMuSkillConfig> skillConfigIdLevelMap = new ConcurrentHashMap<>();

    //开棺宝箱配置
    private Map<Integer, DaoMuCrowbarBoxConfig> crowbarBoxConfigMap;

    //开棺宝箱进度配置
    private Map<Integer, DaoMuProgressConfig> progressConfigMap;

    //摸金等级配置
    private Map<Integer, DaoMuCaptainConfig> captainConfigMap;

    //排序好的摸金等级
    private List<DaoMuCaptainConfig> captainConfigList;

    //PVP
    private Map<Integer, DaoMuPvpConfig> pvpConfigMap = new HashMap<>();

    // pvp技能
    private Map<Integer, DaoMuPvpSkillConfig> pvpSkillConfigMap;

    // pvp榜单
    private Map<Integer, DaoMuPvpRankConfig> pvpRankConfigMap = new HashMap<>();

    //藏品配置
    private Map<Integer, DaoMuCollectionConfig> collectionConfigMap = new ConcurrentHashMap<>();

    //自定义宝箱ID
    private int boxId = 888888;

    private DaoMuPvpCommonConfig pvpCommonConfig;



    /**
     * 构造函数
     *
     * @param activityInfo
     */
     public DaoMuActivityConfig(ActivityInfo activityInfo, Map<String, ActivityConfig> activityConfigMap, Map<Integer, DaoMuMissionConfig> daoMuMissionConfigMap,
                                Map<Integer, DaoMuNpcConfig> daoMuNpcConfigMap, Map<Integer, DaoMuCurioConfig> daoMuCurioConfigMap,
                                Map<Integer, DaoMuPlayerLevelConfig> levelConfigMap, Map<Integer, DaoMuSkillConfig> skillConfigMap,
                                Map<Integer, DaoMuCrowbarBoxConfig> crowbarBoxConfigMap, Map<Integer, DaoMuProgressConfig> progressConfigMap,
                                Map<Integer, DaoMuCaptainConfig> captainConfigMap, Map<Integer, DaoMuPvpConfig> pvpConfigMap, Map<Integer, DaoMuPvpSkillConfig> pvpSkillConfigMap, Map<Integer, DaoMuPvpRankConfig> pvpRankConfigMap) {
         //活动主信息
         this.activityId = activityInfo.getActivityId();
         this.activityInfo = activityInfo;
         //活动配置信息
         this.activityConfigMap = activityConfigMap;
         //关卡配置信息
         this.daoMuMissionConfigMap = daoMuMissionConfigMap;
         //藏品配置信息
         this.daoMuCurioConfigMap = daoMuCurioConfigMap;
         this.daoMuCurioConfigList = new ArrayList<>(daoMuCurioConfigMap.values());
         this.daoMuCurioConfigList.sort(Comparator.comparingLong(DaoMuCurioConfig::getLevel));
         //NPC配置信息
         this.daoMuNpcConfigMap = daoMuNpcConfigMap;
         //等级配置
         this.levelConfigMap = levelConfigMap;
         this.levelConfigList = new ArrayList<>(levelConfigMap.values());
         this.levelConfigList.sort(Comparator.comparingLong(DaoMuPlayerLevelConfig::getLevel));
         //技能配置
         this.skillConfigMap = skillConfigMap;
         for (DaoMuSkillConfig daoMuSkillConfig : skillConfigMap.values()) {
             String key = daoMuSkillConfig.getSkillId() + "_" + daoMuSkillConfig.getLevel();
             this.skillConfigIdLevelMap.put(key, daoMuSkillConfig);
         }
         //开棺宝箱配置
         this.crowbarBoxConfigMap = crowbarBoxConfigMap;
         //开棺宝箱进度配置
         this.progressConfigMap = progressConfigMap;
         //摸金等级
         this.captainConfigMap = captainConfigMap;
         this.captainConfigList = new ArrayList<>(captainConfigMap.values());
         this.captainConfigList.sort(Comparator.comparingLong(DaoMuCaptainConfig::getLevel));
         //藏品配置
         for (DaoMuCurioConfig daoMuCurioConfig : daoMuCurioConfigMap.values()) {
            if (daoMuCurioConfig.getType() == DaoMuCurioTypeEnum.TYPE_COLLECTION.getType()) {
                DaoMuCollectionConfig collectionConfig = new DaoMuCollectionConfig();
                collectionConfig.setCurioId(daoMuCurioConfig.getCurioId());
                collectionConfig.setQuality(daoMuCurioConfig.getQuality());
                collectionConfig.setFavoriteScore(daoMuCurioConfig.getFavoriteScore());
                collectionConfig.setUnlockCond(daoMuCurioConfig.getUnlockCond());
                collectionConfig.setUnlockSkillLevel(Integer.valueOf(daoMuCurioConfig.getUnlockSkillLevel()));
                this.collectionConfigMap.put(daoMuCurioConfig.getCurioId(), collectionConfig);
            }
         }
         //盗墓奇遇(特色服)不加载下面的PVP配置
         if (activityInfo.getType() == eActivityType.DaoMuSpecial.getValue()) {
            return;
         }
         // pvp相关配置
         for (DaoMuPvpConfig pvpConfig : pvpConfigMap.values()) {
             int floor = pvpConfig.getId();
             List<String> connectList = StringUtils.stringToStringList(pvpConfig.getHome(), "\\|");
             for (String connect1 : connectList) {
                 List<String> connect2 = StringUtils.stringToStringList(connect1, "=");
                 if (connect2.size() == 0) {
                     continue;
                 }
                 pvpConfig.getConnectedRoomMap().put(Integer.valueOf(connect2.get(0)),
                         connect2.size() == 1 ?
                                 new ArrayList<>() :
                                 StringUtils.stringToIntegerList(connect2.get(1), ";"));
             }
             // 怪物权重
             List<PropertyWeightItem> mobsWeightList = new ArrayList<>();
             List<String> mobsParamList = StringUtils.stringToStringList(pvpConfig.getMobsId(), "\\#");
             for (String mobsParam : mobsParamList) {
                 mobsWeightList.add(new PropertyWeightItem(PropertyHelper.parseStringToProperty(mobsParam.split(",")[0]), Integer.parseInt(mobsParam.split(",")[1])));
             }
             pvpConfig.setMobsWeightList(mobsWeightList);
             this.pvpConfigMap.put(floor, pvpConfig);
         }
         // pvp技能配置
         this.pvpSkillConfigMap = pvpSkillConfigMap;

         DaoMuPvpCommonConfig pvpCommonConfig = new DaoMuPvpCommonConfig();
         // 参数限制
         pvpCommonConfig.setNumLimit(Integer.parseInt(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_POWER_TIME)));
         // 活动报名时间
         String[] enterNameTimeSplit = getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_ENTER_NAME_TIME).split("\\|");
         pvpCommonConfig.setEnterNameStartTime(Integer.parseInt(enterNameTimeSplit[0].split(";")[0]) * 60 * 60 + Integer.parseInt(enterNameTimeSplit[0].split(";")[1]) * 60);
         pvpCommonConfig.setEnterNameEndTime(Integer.parseInt(enterNameTimeSplit[1].split(";")[0]) * 60 * 60 + Integer.parseInt(enterNameTimeSplit[1].split(";")[1]) * 60);
         // 活动持续时间
         String[] continuedTimeSplit = getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_CONTINUED_TIME).split("\\|");
         pvpCommonConfig.setPvpContinuedStartTime(Integer.parseInt(continuedTimeSplit[0].split(";")[0]) * 60 * 60 + Integer.parseInt(continuedTimeSplit[0].split(";")[1]) * 60);
         pvpCommonConfig.setPvpContinuedEndTime(Integer.parseInt(continuedTimeSplit[1].split(";")[0]) * 60 * 60 + Integer.parseInt(continuedTimeSplit[1].split(";")[1]) * 60);
         // 复活参数
         List<Integer> reviveParamList = StringUtils.stringToIntegerList(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_REVIVE_CD), "\\|");
         pvpCommonConfig.setBaseReviveCd(reviveParamList.get(0));
         pvpCommonConfig.setAddReviveCd(reviveParamList.get(1));
         pvpCommonConfig.setMaxReviveCd(reviveParamList.get(2));
         pvpCommonConfig.setGoodsDisappearTime(Integer.parseInt(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_BOX_DISAPPEAR_TIME)));
         pvpCommonConfig.setProtectCd(Integer.parseInt(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_REVIVE_PROTECT_CD)));

         // pvp属性配置(生命|攻击|防御|生命恢复速度|移动速度|拾取范围|武器携带上限|武器转速|武器恢复间隔)
         List<DaoMuAttributeEnum> configAttributeList = new ArrayList<>();
         configAttributeList.add(DaoMuAttributeEnum.ATTRIBUTE_HP);
         configAttributeList.add(DaoMuAttributeEnum.ATTRIBUTE_ATT);
         configAttributeList.add(DaoMuAttributeEnum.ATTRIBUTE_DEFEND);
         configAttributeList.add(DaoMuAttributeEnum.ATTRIBUTE_RECOVER_HP_PVP);
         configAttributeList.add(DaoMuAttributeEnum.ATTRIBUTE_SPEED);
         configAttributeList.add(DaoMuAttributeEnum.ATTRIBUTE_PICKING_DISTANCE);
         configAttributeList.add(DaoMuAttributeEnum.ATTRIBUTE_BULLET_LIMIT);
         configAttributeList.add(DaoMuAttributeEnum.ATTRIBUTE_BULLET_ROTATIONAL_SPEED);
         configAttributeList.add(DaoMuAttributeEnum.ATTRIBUTE_BULLET_RECOVER);
         // 初始属性值
         List<Long> initAttributeParamList = StringUtils.stringToLongList(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_PARTNER_BASE_PARA), "\\|");
         for (int i = 0; i < initAttributeParamList.size(); i++) {
             pvpCommonConfig.getInitAttributeMap().put(configAttributeList.get(i), initAttributeParamList.get(i));
         }
         // 属性最大值
         List<Long> maxAttributeParamList = StringUtils.stringToLongList(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_PARTNER_BASE_PARA_MAX), "\\|");
         for (int i = 0; i < maxAttributeParamList.size(); i++) {
             pvpCommonConfig.getMaxAttributeMap().put(configAttributeList.get(i), maxAttributeParamList.get(i));
         }

         pvpCommonConfig.setMobsNum(Integer.parseInt(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_MOBS_NUM)));
         pvpCommonConfig.setMobsHateTargetNumMax(Integer.parseInt(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_MOBS_HATE_TARGET_NUM_MAX)));
         pvpCommonConfig.setMobsHateTargetRefreshTime(Integer.parseInt(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_MOBS_HATE_TARGET_REFRESH_TIME)));

         List<String> poolWeightParamList = StringUtils.stringToStringList(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_LNNING_SKILL_POOL_WEIGHTS), "\\|");
         List<NormalWeightItem> weightItemList = new ArrayList<>();
         for (String poolWeight : poolWeightParamList) {
             String[] split = poolWeight.split(",");
             weightItemList.add(new NormalWeightItem(BigInteger.valueOf(Long.parseLong(split[0])), Integer.parseInt(split[1])));
         }
         pvpCommonConfig.setSkillPoolWeights(weightItemList);

         // 公告相关配置
         pvpCommonConfig.setNoticeSingleKill(Integer.parseInt(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_NOTICE_SINGLE_KILL)));
         pvpCommonConfig.setNoticeOneLifeKillNum(StringUtils.stringToIntegerList(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_NOTICE_ONE_LIFE_KILL_NUM),";"));
         pvpCommonConfig.setNoticeOneGameKillNum(StringUtils.stringToIntegerList(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_NOTICE_ONE_GEME_KILL_NUM), ";"));
         for (String collapseTimes : getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_NOTICE_COLLAPSE_TIME).split("\\|")) {
             String[] split = collapseTimes.split("=");
             pvpCommonConfig.getNoticeCollapseTime().put(Integer.parseInt(split[0]), StringUtils.stringToIntegerList(split[1],";"));
         }
         for (String collapseNums : getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_NOTICE_COLLAPSE_NUM).split("\\|")) {
             String[] split = collapseNums.split("=");
             pvpCommonConfig.getNoticeCollapseNum().put(Integer.parseInt(split[0]), StringUtils.stringToIntegerList(split[1],";"));
         }
         for (String disuseNums : getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_NOTICE_DISUSE_NUM).split("\\|")) {
             String[] split = disuseNums.split("=");
             pvpCommonConfig.getNoticeDisuseNum().put(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
         }
         pvpCommonConfig.setNoticeMaxNum(Integer.parseInt(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_NOTICE_SHOW_NUM_MAX)));

         pvpCommonConfig.setInitRoleId(Integer.parseInt(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PARTNER_INITIAL_UNLOCK_ITEM_ID)));

         List<Integer> pvpPixelSize = StringUtils.stringToIntegerList(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_PIXEL_SIZE), "\\|");
         pvpCommonConfig.setRoomMaxWidth(pvpPixelSize.get(0));
         pvpCommonConfig.setRoomMaxHeight(pvpPixelSize.get(1));
         pvpCommonConfig.setRoomShrinkRadius(pvpPixelSize.get(2));
         pvpCommonConfig.setBoxAreaWidth(pvpPixelSize.get(3));
         pvpCommonConfig.setBoxAreaHeight(pvpPixelSize.get(4));
         pvpCommonConfig.setRoomSideSize(pvpPixelSize.get(5));
         pvpCommonConfig.setBirthRadius(pvpPixelSize.get(6));
         pvpCommonConfig.setBoxDropRadius(pvpPixelSize.get(7));
         pvpCommonConfig.setMonsterDropRadius(pvpPixelSize.get(8));
         pvpCommonConfig.setRoleDropRadius(pvpPixelSize.get(9));

         pvpCommonConfig.setPvpDropsHpItem(getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PVP_DROPS_HPITEM));
         this.pvpCommonConfig = pvpCommonConfig;

         this.pvpRankConfigMap = pvpRankConfigMap;
    }

    public int getBoxId() {
        return boxId;
    }

    public int getActivityId() {
        return activityId;
    }

    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public Map<String, ActivityConfig> getActivityConfigMap() {
        return activityConfigMap;
    }

    public Map<Integer, DaoMuMissionConfig> getDaoMuMissionConfigMap() {
        return daoMuMissionConfigMap;
    }

    public Map<Integer, DaoMuCurioConfig> getDaoMuCurioConfigMap() {
        return daoMuCurioConfigMap;
    }

    public List<DaoMuCurioConfig> getDaoMuCurioConfigList() {
        return daoMuCurioConfigList;
    }

    public Map<Integer, DaoMuNpcConfig> getDaoMuNpcConfigMap() {
        return daoMuNpcConfigMap;
    }

    public Map<Integer, DaoMuPlayerLevelConfig> getDaoMuLevelConfigMap() {
        return levelConfigMap;
    }

    public Map<Integer, DaoMuSkillConfig> getDaoMuSkillConfigMap() {
        return skillConfigMap;
    }

    public Map<Integer, DaoMuCrowbarBoxConfig> getCrowbarBoxConfigMap() {
        return crowbarBoxConfigMap;
    }

    public Map<Integer, DaoMuProgressConfig> getProgressConfigMap() {
        return progressConfigMap;
    }

    public Map<Integer, DaoMuCollectionConfig> getCollectionConfigMap() {
        return collectionConfigMap;
    }

    public Map<Integer, DaoMuCaptainConfig> getCaptainConfigMap() {
        return captainConfigMap;
    }

    public Map<Integer, DaoMuPvpConfig> getPvpConfigMap() {
        return pvpConfigMap;
    }

    public Map<Integer, DaoMuPvpSkillConfig> getPvpSkillConfigMap() {
        return pvpSkillConfigMap;
    }

    public DaoMuPvpCommonConfig getPvpCommonConfig() {
        return pvpCommonConfig;
    }

    public Map<Integer, DaoMuPvpRankConfig> getPvpRankConfigMap() {
        return pvpRankConfigMap;
    }

    public void setPvpRankConfigMap(Map<Integer, DaoMuPvpRankConfig> pvpRankConfigMap) {
        this.pvpRankConfigMap = pvpRankConfigMap;
    }

    /**
     * 获取道具配置
     */
    public DaoMuCurioConfig getCurioConfig(int curioId) {
         return this.getDaoMuCurioConfigMap().get(curioId);
    }

    /**
     * 获取活动配置，根据key
     * @param eActivityConfigType
     * @return
     */
    public String getDaoMuActivityConfigValue(eActivityConfigType eActivityConfigType) {
        ActivityConfig activityConfig = this.activityConfigMap.get(eActivityConfigType.getName());
        return activityConfig.getValue();
    }

    /**
     * 获取重随技能消耗元宝数量
     * @param costTime
     * @return
     */
    public int getRandomSkillCostNum(int costTime) {
        String param = this.getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_LNNING_SKILL_REFRESH_COST);
        String[] paramArr = param.split("\\|");
        int initValue = Integer.parseInt(paramArr[0]);
        int addValue = Integer.parseInt(paramArr[1]);
        int maxValue = Integer.parseInt(paramArr[2]);
        return Math.min(initValue + Math.max(costTime - 1, 0) * addValue, maxValue);
    }

    /**
     * 获取积分道具ID
     * @return
     */
    public Integer getScorePropId() {
        return Integer.parseInt(this.getDaoMuActivityConfigValue(eActivityConfigType.EXCHANGE_SCORE_ITEM_ID));
    }

    /**
     * 获取默认关卡
     * @return
     */
    public int getDefaultPassesId() {
        //获取关卡ID最小的关卡
        int minPassesId = 10001;
        for (Integer passesId : daoMuMissionConfigMap.keySet()) {
            if (passesId < minPassesId) {
                minPassesId = passesId;
            }
        }
        return minPassesId;
    }

    /**
     * 获取下一个关卡
     * @param passesId
     * @return
     */
    public int getNextPassesId(int passesId) {
        List<Integer> nextPassesIdList = new ArrayList<>();
        for (DaoMuMissionConfig daoMuMissionConfig : this.daoMuMissionConfigMap.values()) {
            if (daoMuMissionConfig.getId() > passesId) {
                nextPassesIdList.add(daoMuMissionConfig.getId());
            }
        }
        if (nextPassesIdList.size() > 0) {
            //排序
            Collections.sort(nextPassesIdList);
            for (Integer nextPassesId : nextPassesIdList) {
                if (nextPassesId > passesId) {
                    return nextPassesId;
                }
            }
        }
        return passesId;
    }

    /**
     * 获取上一个关卡
     * @param passesId
     * @return
     */
    public int getPrePassesId(int passesId) {
        List<Integer> prePassesIdList = new ArrayList<>();
        for (DaoMuMissionConfig daoMuMissionConfig : this.daoMuMissionConfigMap.values()) {
            if (daoMuMissionConfig.getId() < passesId) {
                prePassesIdList.add(daoMuMissionConfig.getId());
            }
        }
        if (prePassesIdList.size() > 0) {
            //排序
            prePassesIdList.sort(Collections.reverseOrder());
            return prePassesIdList.get(0);
        }
        return passesId;
    }

    /**
     * 获取关卡奖励
     * @param passesId 关卡id
     * @param victoryFlag 是否胜利
     * @param fistFlag 是否首通
     * @return
     */
    public DaoMuReward getPassesReward(int passesId, boolean victoryFlag, boolean fistFlag) {
        DaoMuMissionConfig daoMuMissionConfig = this.daoMuMissionConfigMap.get(passesId);
        Property rewards = new Property();
        Property activityRewards = new Property();
        if (victoryFlag) {
            //背包道具-第一次通关固定奖励
            if (!daoMuMissionConfig.getRewards().equals("0") && fistFlag) {
                Property firstRewards = PropertyHelper.parseNewStringToProperty(daoMuMissionConfig.getRewards());
                rewards.addProperty(firstRewards);
            }
            //活动道具-第一次通关固定奖励
            if (!daoMuMissionConfig.getSpecialRewards().equals("0") && fistFlag) {
                Property specialFirstRewards = PropertyHelper.parseNewStringToProperty(daoMuMissionConfig.getSpecialRewards());
                activityRewards.addProperty(specialFirstRewards);
            }
            //数值背包道具
            if (!daoMuMissionConfig.getSpecialGameRewards().equals("0") && fistFlag) {
                Property firstGameRewards = PropertyHelper.parseNewStringToProperty(daoMuMissionConfig.getSpecialGameRewards());
                rewards.addProperty(firstGameRewards);
            }
        }
        DaoMuReward daoMuReward = new DaoMuReward();
        daoMuReward.setReward(rewards);
        daoMuReward.setActivityReward(activityRewards);
        return daoMuReward;
    }

    /**
     * 获取藏品最大等级
     * @param collectionId
     * @return
     */
    public int getCollectionMaxLevel(int collectionId) {
        int maxLevel = 0;
        for (DaoMuCurioConfig daoMuCurioConfig : this.daoMuCurioConfigMap.values()) {
            if (daoMuCurioConfig.getType() == DaoMuCurioTypeEnum.TYPE_COLLECTION.getType()) {
                if (daoMuCurioConfig.getLevel() > maxLevel) {
                    maxLevel = daoMuCurioConfig.getLevel();
                }
            }
        }
        return maxLevel;
    }

    /**
     * 获取藏品配置信息，根据藏品ID，等级
     * @param collectionId
     * @return
     */
    public DaoMuCurioConfig getCollectionInfo(int collectionId, int level) {
        for (DaoMuCurioConfig daoMuCurioConfig : this.daoMuCurioConfigMap.values()) {
            if (daoMuCurioConfig.getType() == DaoMuCurioTypeEnum.TYPE_COLLECTION.getType()) {
                if (daoMuCurioConfig.getCurioId() == collectionId && daoMuCurioConfig.getLevel() == level) {
                    return daoMuCurioConfig;
                }
            }
        }
        return null;
    }

    /**
     * 获取技能选择MAP
     * @param activeSkillMap 已学习的主动技能MAP
     * @param passiveSkillMap 已学习的被动技能MAP
     * @param unlockSkillMap 解锁的技能MAP
     * @param activeFlag 必中主动技能
     * @return List<DaoMuSkill>
     */
    public List<DaoMuSkill> getSkillSelectList(Map<Integer, DaoMuSkill> activeSkillMap, Map<Integer, DaoMuSkill> passiveSkillMap, Map<Integer, DaoMuSkill> unlockSkillMap, boolean activeFlag) {
        Map<Integer, DaoMuSkill> resultMap = new HashMap<>();
        int maxSelectNum = 3;//可选择技能数
        int maxSkillNum = 6;//最大技能数
        //判断当前是否还有空位可以学习新的类型技能
        if (activeSkillMap.size() >= maxSkillNum && passiveSkillMap.size() >= maxSkillNum) {
            //将当前身上已学习的主动型技能和辅助型技能，根据种类，每种技能各放1个技能在随机池子里，将从池子里随机3个技能展示在界面上供玩家挑选。满级技能需要从池子中排除
            Map<Integer, DaoMuSkill> pool = this.buildStudySkillPool(activeSkillMap, passiveSkillMap, activeFlag);
            //随机出技能
            resultMap = RandomHelper.randomMap(pool, maxSelectNum);
        } else {
            //根据玩家身上已学习的主动型技能、辅助型技能，以及未学习的技能，将技能随机为2个池子
            //需要支持调整池子概率，例如70%概率随机到已学习的池子，30%概率随机到未学习的技能池
            String weights = this.getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_LNNING_SKILL_POOL_TYPE_WEIGHTS);
            String[] weightsArr = weights.split("\\|");
            Map<Integer, DaoMuSkill> studyPool = this.buildStudySkillPool(activeSkillMap, passiveSkillMap, activeFlag);//已学习的技能池子
            Map<Integer, DaoMuSkill> notStudyPool = this.buildNotStudySkillPool(activeSkillMap, passiveSkillMap, unlockSkillMap, activeFlag);//未学习的技能池子
            for (int i = 0 ; i < maxSelectNum; i++) {
                List<Integer> weightList = new ArrayList<>();
                if (studyPool.size() > 0 && notStudyPool.size() > 0) {
                    weightList.add(Integer.valueOf(weightsArr[0]));
                    weightList.add(Integer.valueOf(weightsArr[1]));
                } else {
                    if (studyPool.size() > 0) {
                        weightList.add(100);
                        weightList.add(0);
                    } else if (notStudyPool.size() > 0){
                        weightList.add(0);
                        weightList.add(100);
                    } else {
                        break;
                    }
                }
                //随机池子
                int index = RandomHelper.getRandomIndexByWeight(weightList);
                if (index == 0) {
                    //随机技能-已学习
                    int randomIndex = new Random().nextInt(studyPool.size());
                    Integer randomKey = (Integer) studyPool.keySet().toArray()[randomIndex];
                    DaoMuSkill randomValue = studyPool.get(randomKey);
                    resultMap.put(randomKey, randomValue);
                    studyPool.remove(randomKey);
                } else {
                    //随机技能-未学习
                    int randomIndex = new Random().nextInt(notStudyPool.size());
                    Integer randomKey = (Integer) notStudyPool.keySet().toArray()[randomIndex];
                    DaoMuSkill randomValue = notStudyPool.get(randomKey);
                    resultMap.put(randomKey, randomValue);
                    notStudyPool.remove(randomKey);
                }
            }
        }
        List<DaoMuSkill> result = new ArrayList<>(resultMap.values());
        //不足3格不如回血散
        int recoverHpPropId = this.getDefaultRecoverHpPropId();
        int recoverHpPropNum = maxSelectNum - result.size();
        for (int i = 0; i < recoverHpPropNum; i++) {
            DaoMuSkill daoMuSkill = new DaoMuSkill();
            daoMuSkill.setSkillId(recoverHpPropId);
            daoMuSkill.setSkillLevel(0);
            result.add(daoMuSkill);
        }
        return result;
    }

    /**
     * 构建已学习的技能池子
     * @param activeSkillMap
     * @param passiveSkillMap
     * @param activeFlag 只注入主动技能
     * @return
     */
    public Map<Integer, DaoMuSkill> buildStudySkillPool(Map<Integer, DaoMuSkill> activeSkillMap, Map<Integer, DaoMuSkill> passiveSkillMap, boolean activeFlag) {
        Map<Integer, DaoMuSkill> pool = new HashMap<>();
        //主动技能
        for (DaoMuSkill daoMuSkill : activeSkillMap.values()) {
            int skillId = daoMuSkill.getSkillId();
            //判断是否满级
            boolean fullLevel = this.checkActiveSkillLevelFull(daoMuSkill, passiveSkillMap);
            if (!fullLevel) {
                pool.put(skillId, daoMuSkill);
            }
        }
        if (!activeFlag) {
            //被动技能
            for (DaoMuSkill daoMuSkill : passiveSkillMap.values()) {
                int skillId = daoMuSkill.getSkillId();
                int skillLevel = daoMuSkill.getSkillLevel();
                //判断是否满级
                boolean fullLevel = this.checkPassiveSkillLevelFull(skillLevel);
                if (!fullLevel) {
                    pool.put(skillId, daoMuSkill);
                }
            }
        }
        return pool;
    }

    /**
     * 构建未学习的技能池子
     * @param activeSkillMap
     * @param passiveSkillMap
     * @param unlockSkillMap
     * @param activeFlag 只注入主动技能
     * @return
     */
    public Map<Integer, DaoMuSkill> buildNotStudySkillPool(Map<Integer, DaoMuSkill> activeSkillMap, Map<Integer, DaoMuSkill> passiveSkillMap, Map<Integer, DaoMuSkill> unlockSkillMap, boolean activeFlag) {
        int maxSkillNum = 6;//最大技能数
        Map<Integer, DaoMuSkill> result = new HashMap<>();
        //判断主动技能是否满格
        if (activeSkillMap.size() < maxSkillNum) {
            Map<Integer, DaoMuSkill> notStudyActiveSkillMap = this.getNotStudyActiveSkillMap(activeSkillMap, unlockSkillMap);//未学习，已解锁的主动技能MAP
            result.putAll(notStudyActiveSkillMap);
        }
        if (!activeFlag) {
            //判断被动技能是否满格
            if (passiveSkillMap.size() < maxSkillNum) {
                Map<Integer, DaoMuSkill> notStudyPassiveSkillMap = this.getNotStudyPassiveSkillMap(passiveSkillMap, unlockSkillMap);//未学习，已解锁的被动技能MAP
                result.putAll(notStudyPassiveSkillMap);
            }
        }
        return result;
    }

    /**
     * 获取未学习，已解锁的主动技能MAP
     * @param activeSkillMap 已学的技能
     * @param unlockSkillMap 已解锁的全部技能
     * @return
     */
    public Map<Integer, DaoMuSkill> getNotStudyActiveSkillMap(Map<Integer, DaoMuSkill> activeSkillMap, Map<Integer, DaoMuSkill> unlockSkillMap) {
        Map<Integer, DaoMuSkill> notStudyActiveSkillMap = new HashMap<>();
        for (DaoMuSkill unlockSkill : unlockSkillMap.values()) {
            //技能配置
            DaoMuSkillConfig daoMuSkillConfig = this.getSkillConfig(unlockSkill.getSkillId(), unlockSkill.getSkillLevel());
            //判断是否是主动技能
            if (daoMuSkillConfig.getType() == DaoMuCurioSmallTypeEnum.SMALL_TYPE_ATT.getType()) {
                if (!activeSkillMap.containsKey(unlockSkill.getSkillId())) {
                    notStudyActiveSkillMap.put(unlockSkill.getSkillId(), unlockSkill);
                }
            }
        }
        return notStudyActiveSkillMap;
    }

    /**
     * 获取未学习，已解锁的辅助技能MAP
     * @param passiveSkillMap 已学的技能
     * @param unlockSkillMap 已解锁的全部技能
     * @return
     */
    public Map<Integer, DaoMuSkill> getNotStudyPassiveSkillMap(Map<Integer, DaoMuSkill> passiveSkillMap, Map<Integer, DaoMuSkill> unlockSkillMap) {
        Map<Integer, DaoMuSkill> notStudyPassiveSkillMap = new HashMap<>();
        for (DaoMuSkill unlockSkill : unlockSkillMap.values()) {
            //技能配置
            DaoMuSkillConfig daoMuSkillConfig = this.getSkillConfig(unlockSkill.getSkillId(), unlockSkill.getSkillLevel());
            //判断是否是被动技能
            if (daoMuSkillConfig.getType() == DaoMuCurioSmallTypeEnum.SMALL_TYPE_BE.getType()) {
                if (!passiveSkillMap.containsKey(unlockSkill.getSkillId())) {
                    notStudyPassiveSkillMap.put(unlockSkill.getSkillId(), unlockSkill);
                }
            }
        }
        return notStudyPassiveSkillMap;
    }

    /**
     * 判断被动型技能是否满级
     * @param skillLevel
     * @return
     */
    public boolean checkPassiveSkillLevelFull(int skillLevel) {
        String maxNormalLevelStr = this.getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_LNNING_HAS_ASSISTIVE_SKILL_LEVEL_MAX);
        int maxNormalLevel = Integer.parseInt(maxNormalLevelStr);
        if (skillLevel >= maxNormalLevel) {
            return true;
        }
        return false;
    }

    /**
     * 判断主动型技能是否满级
     * @param daoMuSkill 技能
     * @param passiveSkillMap 被动技能map
     * @return
     */
    public boolean checkActiveSkillLevelFull(DaoMuSkill daoMuSkill, Map<Integer, DaoMuSkill> passiveSkillMap) {
        String maxNormalLevelStr = this.getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_LNNING_NO_ASSISTIVE_SKILL_LEVEL_MAX);
        int maxNormalLevel = Integer.parseInt(maxNormalLevelStr);
        String maxSpecialLevelStr = this.getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_LNNING_HAS_ASSISTIVE_SKILL_LEVEL_MAX);
        int maxSpecialLevel = Integer.parseInt(maxSpecialLevelStr);
        //判断是否有组合的被动型技能
        boolean specialFlag = this.checkSkillComb(daoMuSkill, passiveSkillMap);
        int maxLevel;
        if (specialFlag) {
            maxLevel = maxSpecialLevel;
        } else {
            maxLevel = maxNormalLevel;
        }
        if (daoMuSkill.getSkillLevel() >= maxLevel) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否藏品技能组合
     * @param daoMuSkill 主动技能
     * @param passiveSkillMap 被动技能MAP
     * @return
     */
    public boolean checkSkillComb(DaoMuSkill daoMuSkill, Map<Integer, DaoMuSkill> passiveSkillMap) {
        //获取经详情
        DaoMuSkillConfig daoMuSkillConfig = this.getSkillConfig(daoMuSkill.getSkillId(), daoMuSkill.getSkillLevel());
        //需要有的组合藏品ID
        int combSkillId = daoMuSkillConfig.getCombSkill();
        //判断是否有组合
        if (passiveSkillMap.containsKey(combSkillId)) {
            return true;
        }
        return false;
    }

    /**
     * 开启宝箱，获取的技能
     * @param activeSkillMap 已学习的主动技能MAP
     * @param passiveSkillMap 已学习的被动技能MAP
     * @param unlockSkillMap 解锁的技能MAP
     * @return
     */
    public DaoMuOpenBoxRes openBoxSkillList(Map<Integer, DaoMuSkill> activeSkillMap, Map<Integer, DaoMuSkill> passiveSkillMap, Map<Integer, DaoMuSkill> unlockSkillMap) {
        //已学习技能
        Map<Integer, DaoMuSkill> studySkillMap = this.buildStudySkillPool(activeSkillMap, passiveSkillMap, false);
        //未学习技能
        Map<Integer, DaoMuSkill> notStudySkillMap = this.buildNotStudySkillPool(activeSkillMap, passiveSkillMap, unlockSkillMap, false);

        //选中的技能
        List<DaoMuSkill> selectedSkillMap = this.getBoxSelectedSkill(studySkillMap, notStudySkillMap);
        //全部技能
        List<DaoMuSkill> allSkillMap = this.getBoxAllSkill(selectedSkillMap, studySkillMap, notStudySkillMap);

        //返回
        DaoMuOpenBoxRes result = new DaoMuOpenBoxRes();
        result.setSelectedSkillList(selectedSkillMap);
        result.setAllSkillList(allSkillMap);
        return result;
    }

    /**
     * 获取宝箱选中的技能
     * @param studySkillMap 已学习技能
     * @param notStudySkillMap 未学习技能
     * @return
     */
    public List<DaoMuSkill> getBoxSelectedSkill(Map<Integer, DaoMuSkill> studySkillMap, Map<Integer, DaoMuSkill> notStudySkillMap) {
        Map<Integer, DaoMuSkill> selectedSkillMap;
        //抽取多少个技能
        String weightStr = getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_LNNING_SKILL_POOL_NUM_WEIGHTS);
        int num = RandomHelper.getRandomKeyByWeight(weightStr);
        //先选择【已学习技能】
        selectedSkillMap = RandomHelper.randomMap(studySkillMap, num);
        //补选择【未学习技能】
        if (num > selectedSkillMap.size()) {
            Map<Integer, DaoMuSkill> notStudySelectedSkillMap = RandomHelper.randomMap(notStudySkillMap, num - selectedSkillMap.size());
            selectedSkillMap.putAll(notStudySelectedSkillMap);
        }
        List<DaoMuSkill> list = new ArrayList<>(selectedSkillMap.values());
        //补注入【回血散】
        int recoverHpPropId = this.getDefaultRecoverHpPropId();
        int recoverHpPropNum = num - list.size();
        for (int i = 0; i < recoverHpPropNum; i++) {
            //回血散ID
            DaoMuSkill daoMuSkill = new DaoMuSkill();
            daoMuSkill.setSkillId(recoverHpPropId);
            daoMuSkill.setSkillLevel(0);
            list.add(daoMuSkill);
        }
        return list;
    }

    /**
     * 获取宝箱选中的技能ID list 和 全部技能
     * @param activeSkillMap
     * @param passiveSkillMap
     * @param unlockSkillMap
     * @return
     */
    public DaoMuBoxSelectSkill getBoxSkillIdList(Map<Integer, DaoMuSkill> activeSkillMap, Map<Integer, DaoMuSkill> passiveSkillMap, Map<Integer, DaoMuSkill> unlockSkillMap) {
        //已学习技能
        Map<Integer, DaoMuSkill> studySkillMap = this.buildStudySkillPool(activeSkillMap, passiveSkillMap, false);
        //未学习技能
        Map<Integer, DaoMuSkill> notStudySkillMap = this.buildNotStudySkillPool(activeSkillMap, passiveSkillMap, unlockSkillMap, false);
        return this.getBoxSkillIdList(new ArrayList<>(studySkillMap.values()), new ArrayList<>(notStudySkillMap.values()), passiveSkillMap);
    }

    /**
     * 获取宝箱选中的技能ID list 和 全部技能
     * @param studySkillList 已学习技能
     * @param notStudySkillList 未学习技能
     * @param passiveSkillMap 被动技能map
     * @return DaoMuBoxSelectSkill
     */
    public DaoMuBoxSelectSkill getBoxSkillIdList(List<DaoMuSkill> studySkillList, List<DaoMuSkill> notStudySkillList, Map<Integer, DaoMuSkill> passiveSkillMap) {
        //抽取多少个技能
        String weightStr = getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_LNNING_SKILL_POOL_NUM_WEIGHTS);
        int num = RandomHelper.getRandomKeyByWeight(weightStr);
        //全部技能LIST
        List<Integer> allSkillIdList = new ArrayList<>();
        //【已学习技能】池子
        List<Integer> studySkillIdList = new ArrayList<>();
        for (DaoMuSkill daoMuSkill : studySkillList) {
            //还能升级几次
            int time = this.getSkillCanUpgradeTime(daoMuSkill, passiveSkillMap);
            for (int i = 0; i < time; i++) {
                studySkillIdList.add(daoMuSkill.getSkillId());
            }
        }
        //随机出选中技能
        List<Integer> selectSkillIdList = RandomHelper.getRandomList(studySkillIdList, num);
        //补入all skill list
        for (Integer selectSkillId : selectSkillIdList) {
            if (allSkillIdList.size() < 16) {
                allSkillIdList.add(selectSkillId);
            }
        }
        //补入all skill list
        for (Integer skillId : studySkillIdList) {
            if (allSkillIdList.size() < 16) {
                allSkillIdList.add(skillId);
            }
        }

        //如果不够，继续选择未学习的技能
        int reNum = num - selectSkillIdList.size();
        if (reNum > 0) {
            List<DaoMuSkill> selectNotStudySkillList = RandomHelper.getRandomList(notStudySkillList, reNum);
            for (DaoMuSkill daoMuSkill : selectNotStudySkillList) {
                selectSkillIdList.add(daoMuSkill.getSkillId());
                if (allSkillIdList.size() < 16) {
                    allSkillIdList.add(daoMuSkill.getSkillId());
                }
            }
        }
        //补入all skill list
        for (DaoMuSkill daoMuSkill : notStudySkillList) {
            if (allSkillIdList.size() < 16) {
                allSkillIdList.add(daoMuSkill.getSkillId());
            }
        }

        //如果还不够，补入回血散
        int reReNum = num - selectSkillIdList.size();
        int recoverHpPropId = this.getDefaultRecoverHpPropId();
        for (int i = 0; i < reReNum; i++) {
            selectSkillIdList.add(recoverHpPropId);
            if (allSkillIdList.size() < 16) {
                allSkillIdList.add(recoverHpPropId);
            }
        }

        //如果全部技能还没满足16个
        int allReNum = 16 - allSkillIdList.size();
        for (int i = 0; i < allReNum; i++) {
            allSkillIdList.add(recoverHpPropId);
        }

        DaoMuBoxSelectSkill daoMuBoxSelectSkill = new DaoMuBoxSelectSkill();
        daoMuBoxSelectSkill.setSelectSkillIdList(selectSkillIdList);
        daoMuBoxSelectSkill.setAllSkillIdList(allSkillIdList);
        return daoMuBoxSelectSkill;
    }

    /**
     * 获取技能还能升几级
     * @param daoMuSkill
     * @param passiveSkillMap
     * @return
     */
    private int getSkillCanUpgradeTime(DaoMuSkill daoMuSkill, Map<Integer, DaoMuSkill> passiveSkillMap) {
        String maxNormalLevelStr = this.getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_LNNING_NO_ASSISTIVE_SKILL_LEVEL_MAX);
        int maxNormalLevel = Integer.parseInt(maxNormalLevelStr);
        String maxSpecialLevelStr = this.getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_LNNING_HAS_ASSISTIVE_SKILL_LEVEL_MAX);
        int maxSpecialLevel = Integer.parseInt(maxSpecialLevelStr);
        //判断是否有组合的被动型技能
        boolean specialFlag = this.checkSkillComb(daoMuSkill, passiveSkillMap);
        int maxLevel;
        if (specialFlag) {
            maxLevel = maxSpecialLevel;
        } else {
            maxLevel = maxNormalLevel;
        }
        return maxLevel - daoMuSkill.getSkillLevel();
    }

    /**
     * 获取宝箱全部待选择的技能
     * @param selectedSkillList 已选中技能
     * @param studySkillMap 已学习技能
     * @param notStudySkillMap 未学习技能
     * @return
     */
    public List<DaoMuSkill> getBoxAllSkill(List<DaoMuSkill> selectedSkillList, Map<Integer, DaoMuSkill> studySkillMap, Map<Integer, DaoMuSkill> notStudySkillMap) {
        int selectAllNum = 16;//选择框数量
        Set<Integer> skillSet = new HashSet<>(selectAllNum);
        List<DaoMuSkill> result = new ArrayList<>();
        //注入已选择的技能
        for (DaoMuSkill daoMuSkill : selectedSkillList) {
            if (result.size() < selectAllNum && !skillSet.contains(daoMuSkill.getSkillId())) {
                skillSet.add(daoMuSkill.getSkillId());
                result.add(daoMuSkill);
            }
        }
        //先注入【已学习技能】
        for (DaoMuSkill daoMuSkill : studySkillMap.values()) {
            if (result.size() < selectAllNum  && !skillSet.contains(daoMuSkill.getSkillId())) {
                skillSet.add(daoMuSkill.getSkillId());
                result.add(daoMuSkill);
            }
        }
        //补注入【未学习技能】
        for (DaoMuSkill daoMuSkill : notStudySkillMap.values()) {
            if (result.size() < selectAllNum && !skillSet.contains(daoMuSkill.getSkillId())) {
                skillSet.add(daoMuSkill.getSkillId());
                result.add(daoMuSkill);
            }
        }
        //全部选择，补注入【回血散】
        int recoverHpPropId = this.getDefaultRecoverHpPropId();
        for (int i = 0; i < selectAllNum - skillSet.size(); i++) {
            //回血散ID
            DaoMuSkill daoMuSkill = new DaoMuSkill();
            daoMuSkill.setSkillId(recoverHpPropId);
            daoMuSkill.setSkillLevel(0);
            result.add(daoMuSkill);
        }
        return result;
    }

    /**
     * 获取经验石增加的经验点
     * @param expStoneId
     * @return
     */
    public int getExpStoneExp(int expStoneId) {
        DaoMuCurioConfig daoMuCurioConfig = this.getDaoMuCurioConfigMap().get(expStoneId);
        if (daoMuCurioConfig != null && daoMuCurioConfig.getType() == DaoMuCurioTypeEnum.TYPE_EXP.getType()) {
            return Integer.parseInt(daoMuCurioConfig.getAttributePara());
        }
        return 0;
    }

    /**
     * 获取最大等级
     * @return
     */
    public int getMaxLevel() {
        DaoMuPlayerLevelConfig daoMuPlayerLevelConfig = this.levelConfigList.get(this.levelConfigList.size() - 1);
        return daoMuPlayerLevelConfig.getLevel();
    }

    /**
     * 获取升级所需经验
     * @param level
     * @return
     */
    public int getLevelNeedExp(int level) {
        int needExp = 0;
        for (DaoMuPlayerLevelConfig daoMuPlayerLevelConfig : this.levelConfigList) {
            if (level > daoMuPlayerLevelConfig.getLevel()) {
                needExp += daoMuPlayerLevelConfig.getCost();
            }
        }
        return needExp;
    }

    /**
     * 获取PVE等级，根据经验
     * @param exp
     * @return
     */
    public int getLevelByExp(int exp) {
        int level = 1;
        int cost = 0;
        for (DaoMuPlayerLevelConfig daoMuPlayerLevelConfig : this.levelConfigList) {
            cost += daoMuPlayerLevelConfig.getCost();
            if (exp >= cost) {
                level = daoMuPlayerLevelConfig.getLevel() + 1;
            } else {
                break;
            }
            //达到最大等级，返回
            if (level >= this.levelConfigList.size()) {
                break;
            }
        }
        return level;
    }

    /**
     * 获取摸金等级，根据藏品分
     *
     * 满级cost为0，cost为升到下一级所需的经验
     * 如cost为4000，   0~3999为1级，4000~下一个cost-1为2级
     */
    public int getTouchGoldLevelByExp(long collectionScore) {
        int level = 1;
        for (DaoMuCaptainConfig daoMuCaptainConfig : this.captainConfigList) {
            if (daoMuCaptainConfig.getCost() == 0) {
                // 满级
                break;
            }
            if (collectionScore < daoMuCaptainConfig.getCost()) {
                break;
            }
            level++;
        }
        return level;
    }

    /**
     * 使用止血散恢复的血量
     * @param id 止血散ID
     * @param maxHp
     * @return
     */
    public long getPropRecoverHp(int id, long maxHp) {
        DaoMuCurioConfig daoMuCurioConfig = this.getDaoMuCurioConfigMap().get(id);
        if (daoMuCurioConfig != null && daoMuCurioConfig.getType() == DaoMuCurioTypeEnum.TYPE_STOP_BLEED.getType()) {
            int rate = Integer.parseInt(daoMuCurioConfig.getAttributePara());
            //恢复血量 = 最大HP * 恢复千分比
            BigDecimal recoverHp = BigDecimal.valueOf(maxHp).multiply(BigDecimal.valueOf(rate).divide(BigDecimal.valueOf(1000)));
            return recoverHp.longValue();
        }
        return 0;
    }

    /**
     * 获取NPC血量
     * @param npcId
     * @return
     */
    public int getNpcHp(int npcId){
        DaoMuNpcConfig daoMuNpcConfig = this.getDaoMuNpcConfigMap().get(npcId);
        String basePara = daoMuNpcConfig.getBasePara();
        String[] baseParaArr = basePara.split("\\|");
        return Integer.valueOf(baseParaArr[0]);
    }

    /**
     * 判断BOSS是否是最终BOSS
     * @param passesId
     * @param bossId
     * @return
     */
    public boolean checkFinalBoss(int passesId, int bossId) {
        DaoMuMissionConfig daoMuMissionConfig = this.getDaoMuMissionConfigMap().get(passesId);
        if (daoMuMissionConfig != null) {
            String[] bossArr = daoMuMissionConfig.getBossId().split("\\|");
            if (bossArr.length > 0) {
                int finalBossId = Integer.valueOf(bossArr[bossArr.length - 1]);
                if (bossId == finalBossId) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取NPC掉落的道具
     * @param npcId
     * @return
     */
    public Property getNpcDropProp(int npcId) {
        DaoMuNpcConfig daoMuNpcConfig = this.daoMuNpcConfigMap.get(npcId);
        if (daoMuNpcConfig != null) {
            Property property = PropertyHelper.parseNewStringToProperty(daoMuNpcConfig.getSpecialRewards());
            //是否掉落宝箱
            if (daoMuNpcConfig.getBoxFlag() > 0) {
                property.addProperty(this.boxId, BigInteger.valueOf(1));
            }
            return property;
        }
        return null;
    }

    /**
     * 获取活动道具，根据类型
     * @param daoMuCurioTypeEnum
     * @return
     */
    public Map<Integer, DaoMuCurioConfig> getPropMapByType(DaoMuCurioTypeEnum daoMuCurioTypeEnum) {
        Map<Integer, DaoMuCurioConfig> map = new HashMap<>();
        for (DaoMuCurioConfig daoMuCurioConfig : this.daoMuCurioConfigMap.values()) {
            if (daoMuCurioTypeEnum.getType() == daoMuCurioConfig.getType()) {
                map.put(daoMuCurioConfig.getId(), daoMuCurioConfig);
            }
        }
        return map;
    }

    /**
     * 获取默认止血散ID(最小ID的止血散)
     * @return
     */
    public int getDefaultRecoverHpPropId() {
        Map<Integer, DaoMuCurioConfig> map = this.getPropMapByType(DaoMuCurioTypeEnum.TYPE_STOP_BLEED);
        if (map != null && map.size() > 0) {
            int id = Integer.MAX_VALUE;
            for (DaoMuCurioConfig daoMuCurioConfig : map.values()) {
                if (daoMuCurioConfig.getId() < id) {
                    id = daoMuCurioConfig.getId();
                }
                return id;
            }
        }
        return 40001;
    }

    /**
     * 获取陶罐ID
     * @return
     */
    public int getClayCurioId() {
        for (DaoMuCurioConfig daoMuCurioConfig : this.daoMuCurioConfigMap.values()) {
            if (daoMuCurioConfig.getType() == DaoMuCurioTypeEnum.TYPE_CLAY.getType()) {
                return daoMuCurioConfig.getId();
            }
        }
        return 70001;
    }

    /**
     * 获取藏品唯一id set 根据品质，解锁关卡
     * @param quality 品质
     * @param passesId 解锁关卡
     * @param excludeCollections 排除藏品
     * @return
     */
    public Set<Integer> getCurioUnIdsByQuality(int quality, int passesId, Set<Integer> excludeCollections) {
        Set<Integer> curioUnIdSet = new HashSet<>();
        for (DaoMuCurioConfig daoMuCurioConfig : this.getDaoMuCurioConfigMap().values()) {
            if (daoMuCurioConfig.getType() == DaoMuCurioTypeEnum.TYPE_COLLECTION.getType() && quality == daoMuCurioConfig.getQuality() && daoMuCurioConfig.getLevel() == 1) {
                //判断是否关卡解锁
                if (daoMuCurioConfig.getUnlockCond() == 0 || passesId >= daoMuCurioConfig.getUnlockCond()) {
                    //排除藏品
                    if (!excludeCollections.contains(daoMuCurioConfig.getCurioId())) {
                        curioUnIdSet.add(daoMuCurioConfig.getId());
                    }
                }
            }
        }
        return curioUnIdSet;
    }

    /**
     * 随机藏品，根据品质，解锁关卡
     * @param quality 品质
     * @param passesId 解锁关卡
     * @param excludeCollections 排除藏品
     * @return
     */
    public int getRandomCurioByQuality(int quality, int passesId, Set<Integer> excludeCollections) {
        Set<Integer> curioUnIdSet = this.getCurioUnIdsByQuality(quality, passesId, excludeCollections);
        return RandomHelper.getRandomElement(curioUnIdSet);
    }

    /**
     * 获取藏品唯一id set 根据品质
     * @param quality
     * @return
     */
    public int getRandomCurioByQuality(int quality) {
        Set<Integer> curioUnIdSet = new HashSet<>();
        for (DaoMuCurioConfig daoMuCurioConfig : this.getDaoMuCurioConfigMap().values()) {
            if (daoMuCurioConfig.getType() == DaoMuCurioTypeEnum.TYPE_COLLECTION.getType() && quality == daoMuCurioConfig.getQuality() && daoMuCurioConfig.getLevel() == 1) {
                curioUnIdSet.add(daoMuCurioConfig.getId());
            }
        }
        return RandomHelper.getRandomElement(curioUnIdSet);
    }

    /**
     * 获取宝箱进度LIST
     * @return
     */
    public List<DaoMuProgressConfig> getProgressConfigList() {
        List<DaoMuProgressConfig> list = new ArrayList<>(this.progressConfigMap.values());
        //排序
        list.sort(Comparator.comparingLong(DaoMuProgressConfig::getId));
        return list;
    }

    /**
     * 获取默认进度宝箱ID
     * @return
     */
    public int getDefaultProgressBoxId() {
        if (!getProgressConfigList().isEmpty()) {
            return this.getProgressConfigList().get(0).getId();
        }
        return 0;
    }

    /**
     * 获取下一个宝箱id
     * @return
     */
    public int geNextProgressBoxId(int boxId) {
        List<DaoMuProgressConfig> list = this.getProgressConfigList();
        for (DaoMuProgressConfig daoMuProgressConfig : list) {
            if (daoMuProgressConfig.getId() > boxId) {
                return daoMuProgressConfig.getId();
            }
        }
        return this.getProgressConfigList().get(0).getId();
    }

    /**
     * 检测是否是悬赏的NPC
     * @param passesId
     * @param npcId
     * @return
     */
    public boolean checkIsOfferRewardNpc(int passesId, int npcId) {
        return this.getPassesOfferReward(passesId).containsKey(npcId);
    }

    /**
     * 获取关卡悬赏奖励
     * @param passesId
     * @return
     */
    public Map<Integer, DaoMuReward> getPassesOfferReward(int passesId) {
        Map<Integer, DaoMuReward> result = new HashMap<>();
        DaoMuMissionConfig daoMuMissionConfig = this.getDaoMuMissionConfigMap().get(passesId);
        if (daoMuMissionConfig == null) {
            return result;
        }
        if (StringUtils.isNullOrEmpty(daoMuMissionConfig.getBountyMonster()) || daoMuMissionConfig.getBountyMonster().equals("0")) {
            return result;
        }
        //悬赏的NPC ID
        String[] npcIds = daoMuMissionConfig.getBountyMonster().split("\\|");
        String[] rewards = daoMuMissionConfig.getBountyRewards().split("@");
        String[] activityRewards = daoMuMissionConfig.getSpecialBountyRewards().split("@");
        String[] activityGameRewards = daoMuMissionConfig.getSpecialBountyGameRewards().split("@");
        for (int i = 0; i < npcIds.length; i++) {
            //npc id
            int npcId = Integer.parseInt(npcIds[i]);
            //背包奖励
            Property property = new Property();
            if (!daoMuMissionConfig.getBountyRewards().equals("0")) {
                String reward = rewards[i];
                property.addProperty(PropertyHelper.parseNewStringToProperty(reward));
            }
            //活动奖励
            Property activityProperty = new Property();
            if (!daoMuMissionConfig.getSpecialBountyRewards().equals("0")) {
                String activityReward = activityRewards[i];
                activityProperty.addProperty(PropertyHelper.parseNewStringToProperty(activityReward));
            }
            //数值配置的背包奖励
            if (!daoMuMissionConfig.getSpecialBountyGameRewards().equals("0")) {
                String activityGameReward = activityGameRewards[i];
                Property activityGameProperty = PropertyHelper.parseNewStringToProperty(activityGameReward);
                property.addProperty(activityGameProperty);
            }
            //put result
            DaoMuReward daoMuReward = new DaoMuReward();
            daoMuReward.setReward(property);
            daoMuReward.setActivityReward(activityProperty);
            result.put(npcId, daoMuReward);
        }
        return result;
    }

    /**
     * 获取悬赏ID SET
     * @param passesId
     * @return
     */
    public Set<Integer> getOfferNpcSet(int passesId) {
        Set<Integer> set = new HashSet<>();
        DaoMuMissionConfig daoMuMissionConfig = this.getDaoMuMissionConfigMap().get(passesId);
        if (daoMuMissionConfig == null) {
            return set;
        }
        if (StringUtils.isNullOrEmpty(daoMuMissionConfig.getBountyMonster()) || daoMuMissionConfig.getBountyMonster().equals("0")) {
            return set;
        }
        String[] npcIds = daoMuMissionConfig.getBountyMonster().split("\\|");
        for (String npcIdStr : npcIds) {
            set.add(Integer.parseInt(npcIdStr));
        }
        return set;
    }

    /**
     * 构建 属性 map
     * @param basParaStr
     * @return
     */
    public Map<Integer, DaoMuAttribute> buildAttributeMap(String basParaStr) {
        Map<Integer, DaoMuAttribute> attributeMap = new HashMap<>();
        String maxAttributeStr = this.getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_PARTNER_BASE_PARA_MAX);
        String[] maxAttributeStrArr = maxAttributeStr.split("\\|");
        int attributeId = 1;
        for (String basPara : basParaStr.split("\\|")) {
            //获取最大属性值
            BigDecimal maxValue = BigDecimal.valueOf(Long.parseLong(maxAttributeStrArr[attributeId - 1]));
            BigDecimal value = BigDecimal.valueOf(Long.parseLong(basPara));
            DaoMuAttribute daoMuAttribute = new DaoMuAttribute(attributeId, value, maxValue);
            attributeMap.put(attributeId, daoMuAttribute);
            attributeId++;
        }
        //伤害加成
        DaoMuAttribute harmAddAttribute = new DaoMuAttribute();
        harmAddAttribute.setId(DaoMuAttributeEnum.ATTRIBUTE_HARM_ADD_RATE.getType());
        harmAddAttribute.setValue(BigDecimal.ZERO);
        attributeMap.put(DaoMuAttributeEnum.ATTRIBUTE_HARM_ADD_RATE.getType(), harmAddAttribute);
        return attributeMap;
    }

    /**
     * 构建 属性 map NPC专用
     * @param basParaStr
     * @return
     */
    public Map<Integer, DaoMuAttribute> buildAttributeMapByNpc(String basParaStr) {
        Map<Integer, DaoMuAttribute> attributeMap = new HashMap<>();
        int attributeId = 1;
        for (String basPara : basParaStr.split("\\|")) {
            BigDecimal value = BigDecimal.valueOf(Long.parseLong(basPara));
            DaoMuAttribute daoMuAttribute = new DaoMuAttribute(attributeId, value);
            attributeMap.put(attributeId, daoMuAttribute);
            attributeId++;
        }
        //伤害加成
        DaoMuAttribute harmAddAttribute = new DaoMuAttribute();
        harmAddAttribute.setId(DaoMuAttributeEnum.ATTRIBUTE_HARM_ADD_RATE.getType());
        harmAddAttribute.setValue(BigDecimal.ZERO);
        attributeMap.put(DaoMuAttributeEnum.ATTRIBUTE_HARM_ADD_RATE.getType(), harmAddAttribute);
        return attributeMap;
    }

    /**
     * 获取技能，根据skillId，skillLevel
     * @param skillId
     * @param skillLevel
     * @return
     */
    public DaoMuSkillConfig getSkillConfig(int skillId, int skillLevel) {
        return this.skillConfigIdLevelMap.get(skillId + "_" + skillLevel);
    }

    /**
     * 获取藏品分
     * @param collectionId
     * @return
     */
    public long getFavoriteScore(int collectionId) {
        DaoMuCollectionConfig daoMuCollectionConfig = this.collectionConfigMap.get(collectionId);
        if (daoMuCollectionConfig != null) {
            return daoMuCollectionConfig.getFavoriteScore();
        }
        return 0;
    }

    public DaoMuPvpSkillConfig getDaoMuPvpSkillConfig(int skillId, int level) {
        for (DaoMuPvpSkillConfig skillConfig : pvpSkillConfigMap.values()) {
            if (skillConfig.getSkillId() == skillId && skillConfig.getLevel() == level) {
                return skillConfig;
            }
        }
        return null;
    }

    /**
     * 根据排名获取排名配置
     *
     * @param round 轮次
     * @param rank  当前排名
     */
    public DaoMuPvpRankConfig getDaoMuPvpRankConfig(int round, int rank) {
        DaoMuPvpRankConfig minRankConfig = null;
        for (DaoMuPvpRankConfig config : pvpRankConfigMap.values()) {
            if (config.getRound() == round && rank <= config.getRank()) {
                if (minRankConfig == null || config.getRank() <= minRankConfig.getRank()) {
                    minRankConfig = config;
                }
            }
        }
        return minRankConfig; // 如果没有找到对应的配置，返回null
    }

    /**
     * 判断NPC数量是否达到最大值
     * @param npcNum
     * @return
     */
    public boolean checkNpcNumMax(int npcNum) {
        int maxNum = Integer.parseInt(this.getDaoMuActivityConfigValue(eActivityConfigType.DAOMU_MOBS_NUM_MAX));
        return npcNum >= maxNum;
    }

    /**
     * 判断NPC是否携带该技能
     * @param skillId
     * @return
     */
    public boolean checkNpcSkill(int npcId, int skillId) {
        DaoMuNpcConfig daoMuNpcConfig = this.getDaoMuNpcConfigMap().get(npcId);
        if (daoMuNpcConfig == null) {
            return false;
        }
        String[] skillIds = daoMuNpcConfig.getSkillId().split(";");
        for (String skillIdStr : skillIds) {
            DaoMuSkillConfig daoMuSkillConfig = this.getDaoMuSkillConfigMap().get(Integer.parseInt(skillIdStr));
            if (daoMuSkillConfig.getSkillId() == skillId) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检测NPC的出现是否会自动清除
     * @param npcId
     * @return
     */
    public boolean checkNpcHaveClear(int npcId) {
        DaoMuNpcConfig daoMuNpcConfig = this.getDaoMuNpcConfigMap().get(npcId);
        if (daoMuNpcConfig == null) {
            return false;
        }
        String[] bornPara = daoMuNpcConfig.getBornPara().split(";");
        int showType = Integer.parseInt(bornPara[0]);
        return DaoMuNpcShowTypeEnum.checkClear(showType);
    }

    /**
     * 获取血脉，关卡最该击杀数
     * @param passesId
     * @return
     */
    public int getMobsNumMax(int passesId) {
        DaoMuMissionConfig daoMuMissionConfig = this.getDaoMuMissionConfigMap().get(passesId);
        return daoMuMissionConfig.getMobsNumMax();
    }

    /**
     * 获取战斗特色服技能池，k:技能ID,V:技能对象
     * @return Map<Integer, DaoMuSkill>
     */
    public Map<Integer, DaoMuSkill> getSpecialSkillMap(int passesId) {
        DaoMuMissionConfig muMissionConfig = this.getDaoMuMissionConfigMap().get(passesId);
        String skillListStr = muMissionConfig.getSkillList();
        Map<Integer, DaoMuSkill> result = new HashMap<>();
        String[] skillStrArr = skillListStr.split("\\|");
        for (String skillStr : skillStrArr) {
            String[] skillLevelStr = skillStr.split(";");
            int skillId = Integer.parseInt(skillLevelStr[0]);
            DaoMuSkill skill = new DaoMuSkill();
            skill.setSkillId(skillId);
            skill.setSkillLevel(1);
            result.put(skillId, skill);
        }
        return result;
    }

    /**
     * 获取特色服技能MAP,K:技能ID,V:最高等级
     * @return
     */
    public Map<Integer, Integer> getSpecialSkillLevelMap(int passesId) {
        DaoMuMissionConfig muMissionConfig = this.getDaoMuMissionConfigMap().get(passesId);
        String skillListStr = muMissionConfig.getSkillList();
        Map<Integer, Integer> result = new HashMap<>();
        String[] skillStrArr = skillListStr.split("\\|");
        for (String skillStr : skillStrArr) {
            String[] skillLevelStr = skillStr.split(";");
            int skillId = Integer.parseInt(skillLevelStr[0]);
            int maxLevel = Integer.parseInt(skillLevelStr[1]);
            result.put(skillId, maxLevel);
        }
        return result;
    }

    /**
     * 获取组合技能ID
     * @param activeSkillId
     * @param level
     * @return
     */
    public int getPassiveCombSkillId(int activeSkillId, int level) {
        DaoMuSkillConfig daoMuSkillConfig = this.skillConfigIdLevelMap.get(activeSkillId + "_" + level);
        return daoMuSkillConfig.getCombSkill();
    }

    /**
     * 获取角色道具类型
     * @return
     */
    public int getRoleGoodsType() {
        if (this.getActivityInfo().getChildType() == DaoMuActivityChildTypeEnum.DAOMU.getType()) {
            return eGoodsType.DaoMuRole.getValue();
        } else {
            return eGoodsType.MoJinRole.getValue();
        }
    }
}